package unwrap;

import java.util.ArrayList;
import processing.core.PApplet;
import processing.core.PGraphics;
import toxi.geom.Vec2D;

public class UClip {

	float size = 30;

	public UClip() {

	}

	/**
	 * override this function to create custom clips.
	 * 
	 * <pre>
	 * 	add to your main class: u.clip = new CustomUClip();
	 * 
	 * 	class CustomUClip extends UClip {
	 * 
	 * 		void drawClip(USide s, Vec2D a, Vec2D b, PGraphics pg) {
	 * 			if (s.neighbor != null &amp;&amp; s.sideState == true) {
	 * 				pg.beginShape();
	 * 				pg.vertex(a.x, a.y);
	 * 
	 * 				Vec2D a2 = getRotatedPoint(a, b, -radians(30), 20); // get the 
	 * 				pg.vertex(a2.x, a2.y);
	 * 
	 * 				Vec2D b2 = getRotatedPoint(b, a, radians(30), 20);
	 * 				pg.vertex(b2.x, b2.y);
	 * 
	 * 				pg.vertex(b.x, b.y);
	 * 				pg.endShape();
	 * 
	 * 				drawDottedLine(a, b, 200, pg);
	 * 			} else {
	 * 				pg.line(a.x, a.y, b.x, b.y);
	 * 			}
	 * 		}
	 * 	}
	 * </pre>
	 * 
	 * @param s
	 *            USide
	 * @param Vec2D
	 *            2dpoint a on side s
	 * @param Vec2D
	 *            2dpoint b on side s
	 * @param PGraphics
	 */

	public void drawClip(USide s, Vec2D a, Vec2D b, PGraphics pg) {
		if (s.neighbor != null && s.sideState == true) {
			pg.beginShape();
			pg.vertex(a.x, a.y);

			Vec2D a2 = getRotatedPoint(a, b, -PApplet.radians(30), size);
			pg.vertex(a2.x, a2.y);

			Vec2D b2 = getRotatedPoint(b, a, PApplet.radians(30), size);
			pg.vertex(b2.x, b2.y);

			pg.vertex(b.x, b.y);
			pg.endShape();

			drawDashedLine(a, b, 200, pg);
		} else {
			pg.line(a.x, a.y, b.x, b.y);
		}
	}

	/**
	 * set the default clip size;
	 */
	public void setSize(float _size) {
		size = _size;
	}

	/**
	 * draw a dashed line from a to b
	 * @param Vec2D
	 *            point a
	 * @param Vec2D
	 *            point b
	 * @param float amount of lines
	 * @param PGraphics
	 */
	public void drawDashedLine(Vec2D a, Vec2D b, float amount, PGraphics pg) {
		Vec2D last = a;
		for (int i = 0; i < amount; i++) {
			Vec2D p;
			p = a.interpolateTo(b, i / amount);
			if (i % 3 == 0) {
				pg.line(last.x, last.y, p.x, p.y);
			}
			last = p;
		}
	}

	/**
	 * get the direction from two points and rotate around the first one with
	 * the given angle and distance. returns a point
	 * 
	 * @param Vec2D
	 *            first point
	 * @param Vec2D
	 *            second point
	 * @param float rotation angle around the first point
	 * @param float distance from first point to the new one
	 */
	public Vec2D getRotatedPoint(Vec2D p0, Vec2D p1, float angle, float distance) {
		Vec2D pp1 = p0.sub(p1);
		Vec2D p2 = new Vec2D(distance, 0).getRotated((float) (Math.atan2(pp1.y,
				pp1.x)
				+ Math.PI - angle));
		p2.addSelf(p0);
		return p2;
	}
}
